home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
xvisrc.zip
/
PC386.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-28
|
6KB
|
284 lines
/* Copyright (c) 1990,1991,1992 Chris and John Downey */
#ifndef lint
static char *sccsid = "@(#)pc386.c 2.1 (Chris & John Downey) 7/29/92";
#endif
/***
* program name:
xvi
* function:
PD version of UNIX "vi" editor, with extensions.
* module name:
pc386.c
* module function:
Routines for MS-DOS 386 protected mode version.
This file implements the same routines as ibmpc_a.asm &
msdos_a.asm, which are for the real mode version.
Zortech C++ version 3.0 or later & an appropriate DOS extender
package (such as PharLap's) are required.
* history:
STEVIE - ST Editor for VI Enthusiasts, Version 3.10
Originally by Tim Thompson (twitch!tjt)
Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
Heavily modified by Chris & John Downey
***/
#include "xvi.h"
#include <cerror.h>
#include <controlc.h>
/*
* Virtual mode handling.
*
* On EGA's & VGA's, the number of rows in text modes can vary because
* fonts with different sizes can be loaded, so we use virtual modes
* to contain the additional information needed. (Actually, we handle
* it a bit simplistically because the Zortech display library only
* knows about certain cases: 25 rows (default), 43 rows (EGA with
* 8 x 8 font) & 50 rows (VGA with 8 x 8 font). The last two are
* treated as equivalent.)
*/
#define MONO25X80 2
#define COLOUR25X80 3
#define MDA25X80 7
#define MASK43 043000
#define COLOUR43X80 (COLOUR25X80 | MASK43)
#define MONO43X80 (MONO25X80 | MASK43)
#define MDA43X80 (MDA25X80 | MASK43)
static unsigned
getvmode()
{
unsigned mode;
if ((mode = disp_getmode()) == COLOUR25X80 || mode == MONO25X80 ||
mode == MDA25X80) {
if (disp_numrows > 25) {
return mode | MASK43;
}
}
return mode;
}
static void
setvmode(unsigned vmode)
{
{
int mode;
if (disp_getmode() != (mode = vmode & ~MASK43)) {
disp_close();
disp_setmode(mode);
disp_open();
}
}
{
unsigned m43;
m43 = vmode & MASK43;
if (disp_ega && ((m43 && disp_numrows <= 25) ||
(!m43 && disp_numrows > 25))) {
disp_close();
if (m43) {
disp_set43();
} else {
disp_reset43();
}
disp_open();
}
}
}
static unsigned startmode; /* system virtual mode */
#if 0
/*
* Critical error handler.
*
* See notes in msdos_a.asm.
*/
static int _far _cdecl
criterr(int *pax, int *pdi)
{
*pax = ((_osmajor >= 3) ? 3 : 0);
}
#endif
/*
* Keyboard interrupt handler.
*/
static void _cdecl
inthandler(void)
{
kbdintr = 1;
#if 0
return(-1); /* don't chain to previously installed vector */
#endif
}
/*
* Install interrupt handlers.
*/
void
msdsignal(unsigned char *flagp)
{
_controlc_handler = inthandler;
controlc_open();
#if 0
_cerror_handler = criterr;
cerror_open();
int_intercept(0x23, inthandler, 0);
int_intercept(0x24, criterr, 0);
#endif
}
void
catch_signals(void)
{
/*
* Set console break flag so that we can be interrupted even
* when we're not waiting for console input.
*/
dos_set_ctrl_break(1);
}
/*
* Pointer to copy of previous screen.
*/
static unsigned short *oldscreen = NULL;
void
tty_open(unsigned *prows, unsigned *pcolumns)
{
if (!disp_inited) {
disp_open();
}
startmode = getvmode();
if (disp_base) {
/*
* Allocate storage for copy of previous screen
* (except bottom line).
*
* We don't do this if we're using BIOS calls
* (indicated by disp_base == 0) because the BIOS
* doesn't do it very well (it causes a lot of cursor
* flicker).
*/
oldscreen = (unsigned short *)
malloc((disp_numrows - 1) * disp_numcols *
sizeof(unsigned short));
}
*prows = disp_numrows;
*pcolumns = disp_numcols;
}
static enum {
m_INITIAL = 0,
m_SYS = 1,
m_VI = 2
} curmode;
/*
* Save screen contents & set up video state for editor.
*/
void
tty_startv(void)
{
switch (curmode) {
case m_VI:
/*
* We're already in vi mode.
*/
return;
case m_SYS:
/*
* This isn't the first call. Force display
* package's variables to be re-initialized.
*/
disp_close();
disp_open();
}
curmode = m_VI;
if (getvmode() != startmode) {
/*
* The display mode has changed; set it back to what we
* started with.
*/
setvmode(startmode);
}
if (oldscreen) {
/*
* Save screen contents (except bottom line) so they
* can be restored afterwards.
*/
disp_peekbox(oldscreen, 0, 0, disp_numrows - 2, disp_numcols - 1);
}
msm_init();
/*
* Apparently, the Microsoft mouse driver sometimes
* gets the number of screen rows wrong.
*/
msm_setareay(0, (disp_numrows - 1) * 8);
}
/*
* Restore video state to what it was when we started.
*
* tty_endv() can be called after it's been called already with no
* intervening tty_startv(), so we have to check.
*/
void
tty_endv(void)
{
if (curmode != m_VI) {
return;
}
/*
* Restore contents of screen.
*/
if (oldscreen != NULL) {
disp_pokebox(oldscreen, 0, 0, disp_numrows - 2, disp_numcols - 1);
}
disp_flush();
curmode = m_SYS;
msm_term();
}
#ifndef ABS
# define ABS(n) ((n) < 0 ? -(n) : (n))
#endif
void
pc_scroll(unsigned start, unsigned end, int nlines)
{
if (ABS(nlines) > end + 1 - start) {
nlines = 0;
}
disp_scroll(nlines, start, 0, end, disp_numcols - 1, Pn(P_colour));
}
/*
* Return a character from standard input if one is immediately
* available, otherwise -1.
*
* Don't do anything special if control-C is typed. Just return it.
*/
int
getchnw()
{
union REGS r;
r.h.ah = 6;
r.h.dl = 0xff;
intdos(&r, &r);
return (r.e.flags & 0x40) ? /* zero flag */
-1 : (unsigned char) r.h.al;
}